//
// Created by Tenk2 on 24-5-22.
//

#include "../../inc/dilithium/params.h"
#include "../../inc/dilithium/dilithium.h"


int dilithium_level = -1;
dilithium_params params;

int dilithium_init(int level) {
    if (dilithium_level == level)
        return 1;

    switch (level) {
        case DILITHIUM_NIST2:
            params.K = LV2_K;
            params.L = LV2_L;
            params.ETA = LV2_ETA;
            params.TAU = LV2_TAU;
            params.BETA = LV2_BETA;
            params.GAMMA1 = LV2_GAMMA1;
            params.GAMMA2 = LV2_GAMMA2;
            params.OMEGA = LV2_OMEGA;
            break;

        case DILITHIUM_NIST3:
            params.K = LV3_K;
            params.L = LV3_L;
            params.ETA = LV3_ETA;
            params.TAU = LV3_TAU;
            params.BETA = LV3_BETA;
            params.GAMMA1 = LV3_GAMMA1;
            params.GAMMA2 = LV3_GAMMA2;
            params.OMEGA = LV3_OMEGA;
            break;

        case DILITHIUM_NIST5:
            params.K = LV5_K;
            params.L = LV5_L;
            params.ETA = LV5_ETA;
            params.TAU = LV5_TAU;
            params.BETA = LV5_BETA;
            params.GAMMA1 = LV5_GAMMA1;
            params.GAMMA2 = LV5_GAMMA2;
            params.OMEGA = LV5_OMEGA;
            break;

        default:
            return -1;
    }

    /* POLYVECH_PACKEDBYTES */
    params.POLYVECH_PACKEDBYTES = params.OMEGA + params.K;

    /* POLYZ_PACKEDBYTES */
    if (params.GAMMA1 == (1 << 17)) {
        params.POLYZ_PACKEDBYTES = 576;
    } else if (params.GAMMA1 == (1 << 19)) {
        params.POLYZ_PACKEDBYTES = 640;
    }

    /**
     * POLYW1_PACKEDBYTES
     *
    */
    if (params.GAMMA2 == (Q - 1) / 88) {
        params.POLYW1_PACKEDBYTES = 192;
    }
    else if (params.GAMMA2 == (Q - 1) / 32) {
        params.POLYW1_PACKEDBYTES = 128;
    }

    /* POLYETA_PACKEDBYTES */
    if (params.ETA == 2) {
        params.POLYETA_PACKEDBYTES = 96;
    } else if (params.ETA == 4) {
        params.POLYETA_PACKEDBYTES = 128;
    }

    /* CRYPTO_PUBLICKEYBYTES */
    params.CRYPTO_PUBLICKEYBYTES = SEEDBYTES + params.K * POLYT1_PACKEDBYTES;

    /* CRYPTO_SECRETKEYBYTES */
    params.CRYPTO_SECRETKEYBYTES =
            2 * SEEDBYTES + CRHBYTES + params.L * params.POLYETA_PACKEDBYTES + params.K * params.POLYETA_PACKEDBYTES +
            params.K * POLYT0_PACKEDBYTES;

    /* CRYPTO_BYTES */
    params.CRYPTO_BYTES = SEEDBYTES + params.L * params.POLYZ_PACKEDBYTES + params.POLYVECH_PACKEDBYTES;

    return 0;
}
